using System.ComponentModel.DataAnnotations;
using System.IO;
using FileTransfer.Client;
using FileTransfer.Client.Http.Model;
using FileTransferDesktop.Extensions;
using FileTransferDesktop.Services;
using Wpf.Ui;
using Wpf.Ui.Abstractions.Controls;
using Wpf.Ui.Controls;

namespace FileTransferDesktop.ViewModels.Pages;

public partial class UserProfileViewModel : ObservableValidator, INavigationAware
{
    private readonly IAuthenticationService _authenticationService;
    private readonly ISnackbarService _snackbarService;
    private readonly ApiClient _apiClient;

    #region User Properties
    [ObservableProperty]
    private long _userId;

    [ObservableProperty]
    private string _username = string.Empty;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "显示名称不能为空")]
    [StringLength(50, ErrorMessage = "显示名称不能超过50个字符")]
    private string _displayName = string.Empty;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "邮箱地址不能为空")]
    [EmailAddress(ErrorMessage = "请输入有效的邮箱地址")]
    private string _email = string.Empty;

    [ObservableProperty]
    private string _avatarUrl = string.Empty;

    [ObservableProperty]
    private string _role = string.Empty;

    [ObservableProperty]
    private DateTime _createdAt;

    [ObservableProperty]
    private DateTime _lastLogin;
    #endregion

    #region Password Change Properties
    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "请输入当前密码")]
    private string _currentPassword = string.Empty;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "请输入新密码")]
    [StringLength(128, MinimumLength = 6, ErrorMessage = "密码长度必须在6-128个字符之间")]
    private string _newPassword = string.Empty;

    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "请确认新密码")]
    private string _confirmPassword = string.Empty;
    #endregion

    #region UI State Properties
    [ObservableProperty]
    private bool _isLoading = false;

    [ObservableProperty]
    private bool _isProfileLoading = false;

    [ObservableProperty]
    private bool _isPasswordChanging = false;

    [ObservableProperty]
    private string _loadingMessage = string.Empty;
    #endregion

    #region Error Properties for XAML Binding
    /// <summary>
    /// Gets the first validation error for DisplayName, or empty string if no errors
    /// </summary>
    public string DisplayNameError =>
        GetErrors(nameof(DisplayName)).FirstOrDefault()?.ErrorMessage ?? string.Empty;

    /// <summary>
    /// Gets the first validation error for Email, or empty string if no errors
    /// </summary>
    public string EmailError =>
        GetErrors(nameof(Email)).FirstOrDefault()?.ErrorMessage ?? string.Empty;

    /// <summary>
    /// Gets the first validation error for CurrentPassword, or empty string if no errors
    /// </summary>
    public string CurrentPasswordError =>
        GetErrors(nameof(CurrentPassword)).FirstOrDefault()?.ErrorMessage ?? string.Empty;

    /// <summary>
    /// Gets the first validation error for NewPassword, or empty string if no errors
    /// </summary>
    public string NewPasswordError =>
        GetErrors(nameof(NewPassword)).FirstOrDefault()?.ErrorMessage ?? string.Empty;

    /// <summary>
    /// Gets the first validation error for ConfirmPassword, or empty string if no errors
    /// </summary>
    public string ConfirmPasswordError =>
        GetErrors(nameof(ConfirmPassword)).FirstOrDefault()?.ErrorMessage ?? string.Empty;
    #endregion

    public UserProfileViewModel(
        IAuthenticationService authenticationService,
        ISnackbarService snackbarService,
        IServiceProvider serviceProvider
    )
    {
        _authenticationService = authenticationService;
        _snackbarService = snackbarService;
        _apiClient = serviceProvider.CreateApiClient();
    }

    #region Navigation
    public Task OnNavigatedToAsync()
    {
        _ = LoadUserProfileAsync();
        return Task.CompletedTask;
    }

    public Task OnNavigatedFromAsync()
    {
        // Clean up if needed
        return Task.CompletedTask;
    }
    #endregion

    #region Profile Management
    [RelayCommand]
    private async Task LoadUserProfileAsync()
    {
        try
        {
            IsProfileLoading = true;
            LoadingMessage = "正在加载用户信息...";

            var response = await _apiClient.UserControllerApi.GetCurrentUserAsync();
            if (response?.Data != null)
            {
                var user = response.Data;
                UserId = user.Id;
                Username = user.Username ?? string.Empty;
                DisplayName = user.DisplayName ?? string.Empty;
                Email = user.Email ?? string.Empty;
                AvatarUrl = user.AvatarUrl ?? string.Empty;
                Role = user.Role?.ToString() ?? string.Empty;
                CreatedAt = user.CreatedAt;
                LastLogin = user.LastLogin;

                _snackbarService.Show(
                    "信息加载成功",
                    "用户信息已成功加载",
                    ControlAppearance.Success,
                    null,
                    TimeSpan.FromSeconds(3)
                );
            }
        }
        catch (Exception ex)
        {
            _snackbarService.Show(
                "加载失败",
                $"无法加载用户信息: {ex.Message}",
                ControlAppearance.Danger,
                null,
                TimeSpan.FromSeconds(5)
            );
        }
        finally
        {
            IsProfileLoading = false;
            LoadingMessage = string.Empty;
        }
    }

    [RelayCommand]
    private async Task SaveProfileAsync()
    {
        if (HasErrors)
        {
            _snackbarService.Show(
                "保存失败",
                "请修正表单中的错误后再试",
                ControlAppearance.Caution,
                null,
                TimeSpan.FromSeconds(3)
            );
            return;
        }

        try
        {
            IsLoading = true;
            LoadingMessage = "正在保存用户信息...";

            var updateRequest = new UserUpdateRequest(
                displayName: DisplayName,
                email: Email,
                avatarUrl: AvatarUrl
            );
            var response = await _apiClient.UserControllerApi.UpdateUserAsync(
                UserId,
                updateRequest
            );
            if (response?.Data != null)
            {
                _snackbarService.Show(
                    "保存成功",
                    "用户信息已成功更新",
                    ControlAppearance.Success,
                    null,
                    TimeSpan.FromSeconds(3)
                ); // Update the current user in AuthenticationService to trigger UI updates
                await _authenticationService.RefreshCurrentUserAsync();

                // 刷新用户信息
                await LoadUserProfileAsync();
            }
        }
        catch (Exception ex)
        {
            _snackbarService.Show(
                "保存失败",
                $"无法保存用户信息: {ex.Message}",
                ControlAppearance.Danger,
                null,
                TimeSpan.FromSeconds(5)
            );
        }
        finally
        {
            IsLoading = false;
            LoadingMessage = string.Empty;
        }
    }

    [RelayCommand]
    private async Task ChangePasswordAsync()
    {
        // Validate password confirmation
        if (NewPassword != ConfirmPassword)
        {
            _snackbarService.Show(
                "密码确认失败",
                "新密码和确认密码不一致",
                ControlAppearance.Caution,
                null,
                TimeSpan.FromSeconds(3)
            );
            return;
        }

        if (HasErrors)
        {
            _snackbarService.Show(
                "密码修改失败",
                "请修正表单中的错误后再试",
                ControlAppearance.Caution,
                null,
                TimeSpan.FromSeconds(3)
            );
            return;
        }

        try
        {
            IsPasswordChanging = true;
            LoadingMessage = "正在修改密码...";

            var changeRequest = new ChangePasswordRequest(
                currentPassword: CurrentPassword,
                newPassword: NewPassword
            );

            await _apiClient.UserControllerApi.ChangePasswordAsync(changeRequest);

            _snackbarService.Show(
                "密码修改成功",
                "密码已成功修改，请使用新密码登录",
                ControlAppearance.Success,
                null,
                TimeSpan.FromSeconds(5)
            );

            // Clear password fields
            CurrentPassword = string.Empty;
            NewPassword = string.Empty;
            ConfirmPassword = string.Empty;
        }
        catch (Exception ex)
        {
            _snackbarService.Show(
                "密码修改失败",
                $"无法修改密码: {ex.Message}",
                ControlAppearance.Danger,
                null,
                TimeSpan.FromSeconds(5)
            );
        }
        finally
        {
            IsPasswordChanging = false;
            LoadingMessage = string.Empty;
        }
    }

    [RelayCommand]
    private async Task SelectAvatarAsync()
    {
        try
        {
            var openFileDialog = new OpenFileDialog()
            {
                Title = "选择头像",
                Filter = "图片文件|*.jpg;*.jpeg;*.png;*.gif;*.bmp|所有文件|*.*",
                FilterIndex = 1,
                RestoreDirectory = true,
            };

            if (openFileDialog.ShowDialog() == true)
            {
                await UploadAvatarAsync(openFileDialog.FileName);
            }
        }
        catch (Exception ex)
        {
            _snackbarService.Show(
                "选择头像失败",
                $"无法选择头像文件: {ex.Message}",
                ControlAppearance.Danger,
                null,
                TimeSpan.FromSeconds(3)
            );
        }
    }

    private async Task UploadAvatarAsync(string filePath)
    {
        try
        {
            IsLoading = true;
            LoadingMessage = "正在上传头像...";

            // Create FileParameter from the selected file
            var fileData = System.IO.File.ReadAllBytes(filePath);
            var fileName = Path.GetFileName(filePath);
            var contentType = GetContentType(filePath);
            // Create upload request

            // Upload avatar using the API
            var response = await _apiClient.AvatarControllerApi.UploadAvatarAsync(
                fileName,
                contentType,
                fileData
            );

            if (response?.Data != null && response.Data.ContainsKey("avatarUrl"))
            {
                // Update the avatar URL with the response from server
                AvatarUrl = response.Data["avatarUrl"];

                _snackbarService.Show(
                    "头像上传成功",
                    "头像已成功上传并更新",
                    ControlAppearance.Success,
                    null,
                    TimeSpan.FromSeconds(3)
                );

                // Refresh user info to update the current user avatar in the authentication service
                await _authenticationService.RefreshCurrentUserAsync();
            }
            else
            {
                _snackbarService.Show(
                    "头像上传失败",
                    "服务器返回了无效的响应",
                    ControlAppearance.Danger,
                    null,
                    TimeSpan.FromSeconds(3)
                );
            }
        }
        catch (Exception ex)
        {
            _snackbarService.Show(
                "头像上传失败",
                $"无法上传头像: {ex.Message}",
                ControlAppearance.Danger,
                null,
                TimeSpan.FromSeconds(5)
            );
        }
        finally
        {
            IsLoading = false;
            LoadingMessage = string.Empty;
        }
    }

    private static string GetContentType(string filePath)
    {
        var extension = Path.GetExtension(filePath).ToLowerInvariant();
        return extension switch
        {
            ".jpg" or ".jpeg" => "image/jpeg",
            ".png" => "image/png",
            ".gif" => "image/gif",
            ".bmp" => "image/bmp",
            _ => "application/octet-stream",
        };
    }

    [RelayCommand]
    private async Task ResetProfileAsync()
    {
        var result = System.Windows.MessageBox.Show(
            "确定要重置所有更改吗？这将恢复到上次保存的状态。",
            "确认重置",
            System.Windows.MessageBoxButton.YesNo,
            System.Windows.MessageBoxImage.Question
        );

        if (result == System.Windows.MessageBoxResult.Yes)
        {
            await LoadUserProfileAsync();

            _snackbarService.Show(
                "已重置",
                "用户信息已重置到上次保存的状态",
                ControlAppearance.Info,
                null,
                TimeSpan.FromSeconds(3)
            );
        }
    }
    #endregion

    #region Validation
    partial void OnDisplayNameChanged(string value)
    {
        ValidateProperty(value, nameof(DisplayName));
        OnPropertyChanged(nameof(DisplayNameError));
    }

    partial void OnEmailChanged(string value)
    {
        ValidateProperty(value, nameof(Email));
        OnPropertyChanged(nameof(EmailError));
    }

    partial void OnCurrentPasswordChanged(string value)
    {
        ValidateProperty(value, nameof(CurrentPassword));
        OnPropertyChanged(nameof(CurrentPasswordError));
    }

    partial void OnNewPasswordChanged(string value)
    {
        ValidateProperty(value, nameof(NewPassword));
        OnPropertyChanged(nameof(NewPasswordError));
    }

    partial void OnConfirmPasswordChanged(string value)
    {
        ValidateProperty(value, nameof(ConfirmPassword));
        OnPropertyChanged(nameof(ConfirmPasswordError));
    }
    #endregion
}
